LIBRARY Divide

>DividePN
;****************************************************************************
; Phil's Astounding Divider.  Integer division routine, slightly optimised
; for StrongARM (but there wasn't much space for optimisation).
; If you wish this routine to return the remainder too, just don't bother to
; preserve r2 on the stack - it will return as the remainder.
; On entry:
;	r2  =	Numerator
;	r3  =	Denominator
; On exit:
;	r0  =	Result
; During routine:
;	r0  =	Result build-up
;	r1  =	Accumulator
;	r2  =	Numerator (continuously lowered)
;	r3  =	Denominator (const)
;	r14 =	Shift counter
;============================================================================
	STMFD	r13!,{r1,r2,r14}
	CMP	r2,r3		; Is numerator less than denominator?
	MOV	r0,#0		; Initialise result
	BLT	$Exit		; If so, exit with result
	MOV	r1,r3		; Initialise accumulator
	MOV	r14,#1		; Initialise shift counter

$UpwardLoop
	CMP	r2,r1,LSL #1	; Check accumulator*2 against numerator
	MOV	r4,r4,LSL #1	; Shift shift counter
	MOV	r1,r1,LSL #1	; Shift accumulator up
	BGT	$UpwardLoop	; Branch back
;============================================================================
; The accumulator now contains the highest shift of the denominator which is
; still less than the numerator.  Take this away from the numerator, and add
; the shift value to the result build-up.
;------------------------------------------------------------------------------
$DownwardLoop
	CMP	r1,r2		; Is numerator greater than accumulator?
	SUBLE	r2,r2,r1	; Take accumulator away from numerator
	ADDLE	r0,r0,r4	; Add shift counter to result build-up
	BEQ	$Exit		; Exit if finished division (no remainder left)
	MOV	r1,r1,LSR #1	; Lower accumulator
	MOVS	r4,r4,LSR #1	; Lower shift counter
	BGT	$DownwardLoop	; Go again if there are more positive shifts

$Exit
	LDMFD	r13!,{r1,r2,pc}^
;****************************************************************************
